using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Serilog;
using Volo.Abp;
using Volo.Abp.Data;

namespace WL.Think.Abp;

internal class ThinkDbMigratorHostedService : IHostedService
{
    private readonly IHostApplicationLifetime _hostApplicationLifetime;
    private readonly IConfiguration _configuration;
    private readonly ThinkDbMigratorOptions _options;

    public ThinkDbMigratorHostedService(IHostApplicationLifetime hostApplicationLifetime, IConfiguration configuration, IOptions<ThinkDbMigratorOptions> options)
    {
        _hostApplicationLifetime = hostApplicationLifetime;
        _configuration = configuration;
        _options = options.Value;
    }

    public async Task StartAsync(CancellationToken cancellationToken) 
    {
        if(_options.StartupModuleType == null)
        {
            throw new Exception("StartupModuleType 不能为空");
        }

        using var application = await AbpApplicationFactory.CreateAsync(_options.StartupModuleType, options =>
        {
            options.Services.ReplaceConfiguration(_configuration);
            // 处理服务无法注入的问题，这里不清除为什么服务注册不进容器
            options.Services.AddTransient<ThinkDbMigrationService>();
            options.Services.AddTransient<ThinkOpenIddictDataSeedContributor>();
            options.Services.AddLogging(c => c.AddSerilog());
            options.AddDataMigrationEnvironment();
            options.UseAutofac();
        });
        
        await application.InitializeAsync();

        await application
            .ServiceProvider
            .GetRequiredService<ThinkDbMigrationService>()
            .MigrateAsync();

        await application.ShutdownAsync();

        _hostApplicationLifetime.StopApplication();
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}
